type ICallback = (arg?: unknown) => unknown;

interface IEvents {
  [key: string]: ICallback[]
}

// 自定义事件
function createEmitter() {
  /*
   * 存储自定义事件的容器
   * 容器结构：
   * {
   *    事件名称：[回调函数1, 回调函数2, ...] // 用数组可以保证回调函数的顺序依次触发
   * }
   * */

  const events: IEvents = {}

  return {
    // 绑定自定义事件
    // eventName：事件名称
    // callback：回调函数
    on(eventName: string, callback: ICallback) {
      if (!events[eventName]) {
        events[eventName] = [callback] //第一次添加回调函数
      } else {
        events[eventName].push(callback)
      }
    },
    // 解除自定义事件
    off(eventName: string, callback?: ICallback) {
      /*
       * off('eventName') 解绑该事件（eventName）的所有回调函数
       * off('eventName', cb) 解绑该事件（eventName）的一个回调函数（cb）
       * */

      const callbacks = events[eventName]
      if (!callbacks) {
        return
      }
      if (callback) {
        // 解绑一个
        // 比较函数是否相同，比较的是地址值，将相同的剔除掉
        events[eventName] = callbacks.filter(cb => cb !== callback)
      } else {
        // 解绑所有
        delete events[eventName]
      }
    },
    // 触发自定义事件
    // eventName：事件名称
    // arg：事件参数【可选】
    emit(eventName: string, arg?: unknown) {
      const callbacks = events[eventName]
      // 如果没有该事件就不进行处理
      if (!callbacks) {
        return
      }
      // 遍历所有回调函数一一执行
      callbacks.forEach(cd => cd(arg))
    }
  }
}

const globalEmitter = createEmitter()

export default globalEmitter